
#include "Common/Item/Item.h"
#include "base/core/gamemath.h"
#include "base/core/log.h"
#include "base/core/random.h"
#include "base/core/com_define.h"
#include "Common/TableData/ItemItemCfg.h"
#include "Common/TableData/EquipEquipCfg.h"
#include "Common/TableData/EquipFashionCfg.h"
#include "Common/AttrMgr/AttrMgr.h"
#include "base/core/char_operation.h"
#include "Common/TableDataEx/AreaCfg.h"
#include "Common/TableDataEx/ItemCfg.h"
#include "Common/Utility/ServerTime.h"

CItemBase::CItemBase() :m_nIndex(0),
	m_nItemID(0),
	m_nNum(0), 
	m_byBind((uint8_t)EBindState::EBindState_no),
	m_byType((uint8_t)EPackageLabel_none)
{
	memset(m_szMaker, 0, sizeof(m_szMaker));
}

CItemBase::~CItemBase()
{

}
//初始化
bool CItemBase::Init(uint16_t nIndex, uint32_t nItemID, SItemCond &itemCond, uint32_t nNum /*= 1*/, int8_t byBind /*= (int8_t)EBindState::EBindState_no*/)
{
	_UNUSE(itemCond);
	m_nIndex = nIndex;
	m_nItemID = nItemID;
	m_nNum = nNum;
	m_byBind = byBind;

	return true;
}

void CItemBase::UnInit()
{
	m_nIndex = 0;
	m_nItemID = 0;
	m_nNum = 0;
	m_byBind = (uint8_t)EBindState::EBindState_no;
	m_byType = 0;
	memset(m_szMaker, 0, sizeof(m_szMaker));
}

//获取索引
uint16_t CItemBase::GetIndex() const
{
	return m_nIndex;
}
//设置索引
void CItemBase::SetIndex(uint16_t nIndex)
{
	m_nIndex = nIndex;
}

//获取物品ID
uint32_t CItemBase::GetItemID() const
{
	return m_nItemID;
}
//获取类型
uint8_t CItemBase::GetType()
{
	return m_byType;
}
//获取打造者名字
const char *CItemBase::GetMaker()
{
	return m_szMaker;
}
//设置打造者名字
void CItemBase::SetMaker(const char *szMaker)
{
	if (nullptr == szMaker)
	{
		memset(m_szMaker, 0, sizeof(m_szMaker));
	}
	else
	{
		SafeCopyString(m_szMaker, sizeof(m_szMaker), szMaker);
	}
	
}
//获取数量
uint32_t CItemBase::GetNum() const
{
	return m_nNum;
}
//设置数量
void CItemBase::SetNum(uint32_t nNum)
{
	m_nNum = nNum;
}
//增加数量
bool CItemBase::AddNum(int32_t nAddNum)
{
	if (nAddNum > 0)
	{
		if (UINT32_MAX - m_nNum < (uint32_t)nAddNum)
		{
			m_nNum = UINT32_MAX;
			//数量超过 需要打印警告日志
			MMOLOG_FMT_ERROR("[logic] CItemBase::AddNum....num > UINT32_MAX...nAddNum:%u,m_nNum:%u", nAddNum, m_nNum);
		}
		else
		{
			m_nNum += nAddNum;
		}
	}
	else
	{
		if (((int64_t)m_nNum + (int64_t)nAddNum) >=0 )
		{
			m_nNum += nAddNum;
		}
		else
		{
			m_nNum = 0;
		}
	}
	
	return true;	
}
//获取绑定状态
int8_t CItemBase::GetBind() const
{
	return m_byBind;
}
//设置绑定状态
void CItemBase::SetBind(int8_t byBind)
{
	m_byBind = byBind;
}

//设置物品信息
bool CItemBase::SetItemProto(const ItemProtoInfo &protoItem)
{
	m_nIndex = protoItem.index();
	m_nItemID = protoItem.item_id();
	m_nNum = protoItem.item_num();
	m_byBind = protoItem.bind();
	if (protoItem.has_maker())
	{
		SafeCopyString(m_szMaker, sizeof(m_szMaker), protoItem.maker().c_str()); //打造者
	}
	return true;
}

//拷贝
bool CItemBase::CopyFrom(const CItemBase *pItemCopy)
{
	if (nullptr == pItemCopy)
	{
		return false;
	}
	CItemBase *pItemCopyEx = const_cast<CItemBase*>(pItemCopy);
	m_nIndex = pItemCopyEx->GetIndex();		//索引
	m_nItemID = pItemCopyEx->GetItemID();	//物品ID
	m_nNum = pItemCopyEx->GetNum();			//物品数量
	m_byBind = pItemCopyEx->GetBind();		//绑定状态
	m_byType = pItemCopyEx->GetType(); 		//类型
	if (nullptr != pItemCopyEx->GetMaker())
	{
		SafeCopyString(m_szMaker, sizeof(m_szMaker), pItemCopyEx->GetMaker()); //打造者
	}
	
	return true;
}

///////////////////////////////////  普通物品  ///////////////////////////////////////

CItem::CItem() :m_nAreaId(0), m_nActiveStatus(0), m_nFund(0), m_nAvePrice(0), m_nConfigTimes(0), m_nUseTimes(0)
{
	m_MarkList.clear();
	m_nHpMpValue = 0;
	m_byType = EItemType_common;
}

CItem::~CItem()
{
	
}

//初始化
bool CItem::Init(uint16_t nIndex, uint32_t nItemID, SItemCond &itemCond, uint32_t nNum /*= 1*/, int8_t byBind /*= (uint8_t)EBindState::EBindState_no*/)
{
	bool ret = CItemBase::Init(nIndex, nItemID, itemCond, nNum, byBind);
	if (!ret)
	{
		return false;
	}
	const ItemItemCfgInfo *pItemCfg = g_GetItemItemCfgTable()->GetItemItemCfgInfo(nItemID);
	if (nullptr == pItemCfg)
	{
		MMOLOG_FMT_ERROR("[logic] nullptr == pItemCfg...nItemID:%u ", nItemID);
		return false;
	}
	if ((int32_t)EItemFuncType::EItemFuncType_TreasureMap_Active == pItemCfg->functionType || (int32_t)EItemFuncType::EItemFuncType_TreasureMap_NoActive == pItemCfg->functionType)
	{
		//随机一个藏宝图区域，藏宝图激活之后才会有区域ID,激活之后才会到指定区域去挖宝
		m_nAreaId = g_GetAreaCfgMgr()->RandTreasureAreaId(itemCond.camp,itemCond.level);
	}
	else if ((int32_t)EItemFuncType::EItemFuncType_RunBusiness == pItemCfg->functionType)
	{
		//设置跑商商券 初始资金  functionType=19 目标资金,初始资金
		const VEC_INT32 *pFuncParam = g_GetItemCfgMgr()->GetItemFuncParamCfg(nItemID);
		if (nullptr != pFuncParam && pFuncParam->size() >=2 )
		{
			m_nFund = pFuncParam->at(1);
		}
	}
	else if ((int32_t)EItemFuncType::EItemFuncType_StarSoul == pItemCfg->functionType)
	{
		//设置可使用次数  functionType=20 
		const VEC_INT32 *pFuncParam = g_GetItemCfgMgr()->GetItemFuncParamCfg(nItemID);
		if (nullptr != pFuncParam && pFuncParam->size() >= 1)
		{
			m_nConfigTimes = pFuncParam->at(0);
			m_nUseTimes = 0;
		}
	}
	else if ((int32_t)EItemFuncType::EItemFuncType_HpMpBox == pItemCfg->functionType)
	{
		//血包类物品  functionType=25 关联属性（1，生命；2，魔法），最大上限值
		const VEC_INT32 *pFuncParam = g_GetItemCfgMgr()->GetItemFuncParamCfg(nItemID);
		if (nullptr != pFuncParam && pFuncParam->size() >= 2)
		{
			m_nHpMpValue = pFuncParam->at(1);
		}
	}

	return true;
}
//
void CItem::UnInit()
{
	CItemBase::UnInit();
	m_nAreaId = 0;
	m_nActiveStatus = 0;
	m_nFund = 0;
	m_nConfigTimes = 0;
	m_nUseTimes = 0;
	m_MarkList.clear();
	m_nHpMpValue = 0;
}

//获取藏宝图区域ID
uint32_t CItem::GetAreaId()
{
	return m_nAreaId;
}
//获取激活状态
int8_t  CItem::ActiveStatus()
{
	return m_nActiveStatus;
}
//设置激活状态
void  CItem::ActiveStatus(int8_t status)
{
	m_nActiveStatus = status;
}
//获取资金
int32_t CItem::GetFund() const
{
	return m_nFund;
}
//设置资金
void CItem::SetFund(int32_t fund)
{
	m_nFund = fund;
}

//获取均价
int32_t CItem::GetAvePrice() const
{
	return m_nAvePrice;
}
//设置均价
void CItem::SetAvePrice(int32_t price)
{
	m_nAvePrice = price;
}

//获取血包类物品 血蓝上限值
int32_t CItem::GetHpMpValue() const
{
	return m_nHpMpValue;
}
//设置血包类物品  血蓝上限值
void CItem::SetHpMpValue(int32_t hpmpVal)
{
	m_nHpMpValue = hpmpVal;
}

//获取可使用次数
int32_t CItem::GetConfigTimes() const
{
	return m_nConfigTimes;
}
void CItem::SetConfigTimes(int32_t times)
{
	m_nConfigTimes = times;
}
//获取已使用次数
int32_t CItem::GetUseTimes() const
{
	return m_nUseTimes;
}
void CItem::SetUseTimes(int32_t times)
{
	m_nUseTimes = times;
}

//获取标记坐标
vector<CMarkPos>* CItem::GetMarkPos()
{
	return &m_MarkList;
}

//设置物品信息
bool CItem::SetItemProto(const ItemProtoInfo &protoItem)
{
	bool ret = CItemBase::SetItemProto(protoItem);
	if (ret)
	{
		if (protoItem.has_areaid())
		{
			m_nAreaId = protoItem.areaid();
		}	
		if (protoItem.has_active())
		{
			m_nActiveStatus = protoItem.active();
		}
		if (protoItem.has_fund())
		{
			m_nFund = protoItem.fund();
		}
		if (protoItem.has_ave_price())
		{
			m_nAvePrice = protoItem.ave_price();
		}
		if (protoItem.has_hpmp_value())
		{
			m_nHpMpValue = protoItem.hpmp_value();
		}
		if (protoItem.has_soul())
		{
			m_nConfigTimes = protoItem.soul().confing_times();
			m_nUseTimes = protoItem.soul().use_times();
			if (protoItem.soul().mark_list_size() > 0)
			{
				m_MarkList.clear();
				uint16_t size = protoItem.soul().mark_list_size();
				for (uint16_t i = 0; i < size; i++)
				{
					CMarkPos mPos;
					mPos.mapId = protoItem.soul().mark_list(i).map_id();
					mPos.pos.x = protoItem.soul().mark_list(i).pos().x();
					mPos.pos.y = protoItem.soul().mark_list(i).pos().y();
					mPos.pos.z = protoItem.soul().mark_list(i).pos().z();
					m_MarkList.push_back(mPos);
				}
			}
		}
	}
	return ret;
}
//拷贝
bool CItem::CopyFrom(const CItemBase *pItemCopy)
{
	if (!CItemBase::CopyFrom(pItemCopy))
	{
		return false;
	}
	CItemBase *pItemCopyEx = const_cast<CItemBase*>(pItemCopy);
	m_nAreaId = pItemCopyEx->GetAreaId();
	m_nActiveStatus = pItemCopyEx->ActiveStatus();
	m_nFund = pItemCopyEx->GetFund();
	m_nHpMpValue = pItemCopyEx->GetHpMpValue();
	m_nConfigTimes = pItemCopyEx->GetConfigTimes();
	m_nUseTimes = pItemCopyEx->GetUseTimes();
	m_MarkList = *pItemCopyEx->GetMarkPos();
	return true;
}

//////////////////////////////////  装备 ////////////////////////////////////////


CEquip::CEquip() :m_identify(true), m_addByDeputy(false), m_nFight(0), m_nTotalFight(0)
{
	m_byType = EItemType_equip;
	m_mapBase.clear();
	m_mapRefineExt.clear();

	m_nRefineLev = 0;
	m_nHoly = 0;
	m_vecInaly.clear();

	//static uint16_t STONE_SLOT_COUNT = 4;	//默认开四个槽
	m_vecInaly.resize(MAX_EQUIP_HOLE_NUM, 0);

	m_endTick = 0;
}

CEquip::~CEquip()
{

}

//初始化
bool CEquip::Init(uint16_t nIndex, uint32_t nItemID, SItemCond &itemCond, uint32_t nNum /*= 1*/, int8_t byBind /*= (uint8_t)EBindState::EBindState_no*/)
{
	bool ret = CItemBase::Init(nIndex, nItemID, itemCond,nNum, byBind);
	if (!ret)
	{
		return false;
	}
	const EquipEquipCfgInfo *pEquip = g_GetEquipEquipCfgTable()->GetEquipEquipCfgInfo(nItemID);
	if (nullptr == pEquip)
	{
		MMOLOG_FMT_ERROR("[logic] nullptr == pEquip...nItemID:%u ", nItemID);
		return false;
	}
	//神装
	if (pEquip->gold == 2)
	{
		m_endTick = (pEquip->time > 0) ? (g_GetGlobalServerTime()->UnixSec() + pEquip->time * 60) : -10000/*永久神装标志*/;
	}
	//随机基础属性
	const VecEquipEquipAttributeCfg &vecBaseAttr = pEquip->vecEquipEquipAttributeCfg;
	VecEquipEquipAttributeCfg::const_iterator iter = vecBaseAttr.begin();
	for (; iter != vecBaseAttr.end(); ++iter)
	{
		const EquipEquipAttributeCfgInfo &attr = (*iter);
		uint32_t pattrID = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip, attr.type);
		if (P_NONE != pattrID)
		{
			if (EItemInitAttrType_Common == itemCond.inittype)
			{
				m_mapBase[pattrID] = Random(attr.valueMin, attr.valueMax);
			}
			else if (EItemInitAttrType_NpcShop == itemCond.inittype) //NPC商店物品 基础属性取最小值
			{
				m_mapBase[pattrID] = attr.valueMin;
			}
			else if (EItemInitAttrType_Duputy == itemCond.inittype)
			{
				m_mapBase[pattrID] = Random(attr.valueMin, attr.valueMax);
				m_mapBase[pattrID] += m_mapBase[pattrID] * 10.0f / 100.0f;
				m_addByDeputy = true;
			}
		}
	}

	if (EItemInitAttrType_Common == itemCond.inittype || EItemInitAttrType_Duputy == itemCond.inittype) //通用的初始化属性类型
	{
		//随机精炼属性条数
		int32_t refineAttrNum = Random(pEquip->refineAttributeDown, pEquip->refineAttributeUp);
		if (refineAttrNum > 0)
		{
			VEC_INT32 vecAttrType;
			VEC_INT32 vecAttrMinValue;
			VEC_INT32 vecAttrMaxValue;
			vecAttrType.clear();
			vecAttrMinValue.clear();
			vecAttrMaxValue.clear();
			CommonApi::SplitStrToVecInt(pEquip->refineAttribute_valueMin, ",", &vecAttrMinValue);
			CommonApi::SplitStrToVecInt(pEquip->refineAttribute_valueMax, ",", &vecAttrMaxValue);
			CommonApi::SplitStrToVecInt(pEquip->refineAttribute_typeLibrary, ",", &vecAttrType);
			if (vecAttrMaxValue.size() == vecAttrMinValue.size()
				&& vecAttrMaxValue.size() == vecAttrType.size()
				&& vecAttrMaxValue.size() >= (uint32_t)refineAttrNum
				)
			{
				for (int32_t i = 0; i < refineAttrNum; ++i)
				{
					int32_t idx = Random(vecAttrType.size());
					int32_t attrId = vecAttrType.at(idx);
					int32_t attrVal = Random(vecAttrMinValue.at(idx), vecAttrMaxValue.at(idx));
					uint32_t pattrID = g_GetAttrMgr()->GetPlayerFightModlePAttr(enFightAttrModule_Equip,attrId);
					if (P_NONE != pattrID)
					{
						MAP_INT32_INT32::iterator iterRefine = m_mapRefineExt.find(pattrID);
						if (iterRefine != m_mapRefineExt.end())
						{
							LogErrFmtPrint("[logic] CEquip::Init.... random same attrid.... itemid:%u, attrid:%d, pattrid:%u ", m_nItemID, attrId, pattrID);
						}

						m_mapRefineExt[pattrID] = attrVal;

						vecAttrType.erase(vecAttrType.begin() + idx);
						vecAttrMinValue.erase(vecAttrMinValue.begin() + idx);
						vecAttrMaxValue.erase(vecAttrMaxValue.begin() + idx);
					}
					else
					{
						LogErrFmtPrint("[logic] CEquip::Init....GetPlayerEquipPAttr not find p attrid.....attrid:%d, itemid:%u ", m_nItemID, attrId);
					}
				}
			}
			else
			{
				LogErrFmtPrint("[logic] CEquip::Init...init refine attr error....nItemID:%u,refineAttrNum:%d, vecAttrMaxValueSize:%d,vecAttrMinValueSize:%d, vecAttrTypeSize:%d ", nItemID, refineAttrNum, (int32_t)vecAttrMaxValue.size(), (int32_t)vecAttrMinValue.size(), (int32_t)vecAttrType.size());
			}
		}
	}
	else if (EItemInitAttrType_NpcShop == itemCond.inittype) //NPC商店物品 没有附加属性
	{

	}

	return true;
}
//
void CEquip::UnInit()
{
	CItemBase::UnInit();
	m_identify = false;
	m_nFight = 0;
	m_nTotalFight = 0;
	m_mapBase.clear();
	m_mapRefineExt.clear();
	m_nRefineLev = 0;
	m_nHoly = 0;
	m_vecInaly.clear();
}

//获取战力值
uint32_t CEquip::GetFight()
{
	return m_nFight;
}
//设置战力值
void CEquip::SetFight(uint32_t nFight)
{
	m_nFight = nFight;
}

uint32_t CEquip::GetTotalFight()
{
	return m_nTotalFight;
}
void CEquip::SetTotalFight(uint32_t nFight)
{
	m_nTotalFight = nFight;
}

int64_t CEquip::GetEndTick()
{
	return m_endTick;
}
void CEquip::SetEndTick(int64_t tick)
{
	m_endTick = tick;
}

//获取精炼额外属性
MAP_INT32_INT32 *CEquip::GetRefineEx()
{
	return &m_mapRefineExt;
}
//获取基础属性
MAP_INT32_INT32 *CEquip::GetBaseAttr()
{
	return &m_mapBase;
}

uint16_t CEquip::GetRefineLev()
{
	return m_nRefineLev;
}

void CEquip::SetRefineLev(uint16_t nRefineLev)
{
	m_nRefineLev = nRefineLev;
}

uint32_t CEquip::GetHoly()
{
	return m_nHoly;
}

void CEquip::SetHoly(uint32_t nHoly)
{
	m_nHoly = nHoly;
}

VEC_UINT32* CEquip::GetInlay()
{
	return &m_vecInaly;
}

bool CEquip::AddByDeputy()
{
	return m_addByDeputy;
}
void CEquip::AddByDeputy(bool add)
{
	m_addByDeputy = add;
}

//设置物品信息
bool CEquip::SetItemProto(const ItemProtoInfo &protoItem)
{
	bool bRet = CItemBase::SetItemProto(protoItem);
	if (bRet)
	{
		if (protoItem.has_naked_fight())
		{
			m_nFight = protoItem.naked_fight();
		}
		if (protoItem.has_total_fight())
		{
			m_nTotalFight = protoItem.total_fight();
		}
		if (protoItem.has_refinelv())
		{
			m_nRefineLev = protoItem.refinelv();
		}
		if (protoItem.has_identify())
		{
			m_identify = protoItem.identify();
		}
		if (protoItem.has_holy())
		{
			m_nHoly = protoItem.holy();
		}
		if (protoItem.has_add_by_deputy())
		{
			m_addByDeputy = protoItem.add_by_deputy();
		}
		if (protoItem.has_end_tick())
		{
			m_endTick = protoItem.end_tick();
		}
		uint16_t baseSize = protoItem.baseattr_size();
		for (uint16_t i = 0; i < baseSize; ++i)
		{
			const Attr &attr = protoItem.baseattr(i);
			m_mapBase[attr.attrnum()] = attr.attrvalue();
		}

		uint16_t refineexSize = protoItem.refineex_size();
		for (uint16_t j = 0; j < refineexSize; ++j)
		{
			const Attr &attr = protoItem.refineex(j);
			m_mapRefineExt[attr.attrnum()] = attr.attrvalue();
		}

		uint16_t inlaySize = protoItem.inlay_size();
		for (uint16_t i = 0; i < inlaySize; ++i)
		{
			m_vecInaly[i] = protoItem.inlay((i));
		}
	}

	return bRet;
}

//拷贝
bool CEquip::CopyFrom(const CItemBase *pItemCopy)
{
	if (!CItemBase::CopyFrom(pItemCopy))
	{
		return false;
	}
	CItemBase *pItemCopyEx = const_cast<CItemBase*>(pItemCopy);

	m_nFight = pItemCopyEx->GetFight();
	m_nTotalFight = pItemCopyEx->GetTotalFight();
	m_nRefineLev = pItemCopyEx->GetRefineLev();
	m_identify = pItemCopyEx->Identify();
	m_nHoly = pItemCopyEx->GetHoly();
	m_endTick = pItemCopyEx->GetEndTick();

	//镶嵌宝石
	m_vecInaly.clear();
	VEC_UINT32 *pInlay = pItemCopyEx->GetInlay();
	if (nullptr != pInlay)
	{
		m_vecInaly = *pInlay;
	}

	//基础属性
	m_mapBase.clear();
	MAP_INT32_INT32 *pBaseAttr = pItemCopyEx->GetBaseAttr();
	if (nullptr != pBaseAttr)
	{
		m_mapBase = *pBaseAttr;
	}

	//精炼额外属性
	m_mapRefineExt.clear();
	MAP_INT32_INT32 *pRefine = pItemCopyEx->GetRefineEx();
	if (nullptr != pRefine)
	{
		m_mapRefineExt = *pRefine;
	}	

	return true;
}